import DrawsAbstract from "../DrawsAbstract";
import gsap from 'gsap';
import Rect from "../Rect";

export class DrawBox extends DrawsAbstract{
    drawStyle = {
        size: {
            width: 100,
            height: 100
        },
        position: {
            x: 100,
            y: 100
        },
        colorObj: {
            borderColor: 'rgba(99,110,114,0)',
            mainBoxFill: 'rgba(116,185,255,0)',
            mainLockBgColor: 'rgba(99,110,114,0)',
            mainShadowBgColor: 'rgba(104,165,227,0)',
            contentBoxFill: 'rgba(92,144,200,0)',
            topBoxFill: 'rgba(107,171,237,0)',
        },
        base: {
            lineWidth: 10
        },
        mainBox: {
            lock: {
                width: 0.1,
                height: 0.1,
                radius: 0,
                data: [{
                    x: 0.2,
                    y: 0
                }, {
                    x: 0.7,
                    y: 0
                }]
            },
            shadow: {
                x: 0,
                y: 0,
                width: 1,
                height: 0.1,
                radius: 0
            },
            rect: {
                x: 0.1,
                y: 0.6,
                width: 0.8,
                height: 0.4,
                radius: 0
            }
        },
        contentBox: {
            lineWidth: 10,
            rect: {
                x: 0.11,
                y: 0.4,
                width: 0.78,
                height: 0.15,
                preset: 0.9,
                type: 'top',
                radius: 1
            }
        },
        topBox: {
            lineWidth: 10,
            lock: {
                width: 0.1,
                height: 0.15,
                radius: 0,
                data: [{
                    x: 0.2,
                    y: 0
                }, {
                    x: 0.7,
                    y: 0
                }]
            },
            rect: {
                x: 0.15,
                y: 0,
                width: 0.7,
                height: 0.4
            }
        }
    }

    constructor(ctx: CanvasRenderingContext2D, size?: {width: number, height: number}, position?: {x: number, y: number}) {
        super(ctx);
        size && (this.drawStyle.size = size)
        position && (this.drawStyle.position = position)
    }

    realDraw() {
        this.drawTopBox()
        this.drawContentBox()
        Promise.resolve().then(() => {
            this.drawMainBox()
        })
    }

    in() {
        this.drawStyle.size = this.size;
        this.drawStyle.position = this.position
        gsap.to(this.drawStyle.colorObj, {
            duration: this.baseDuration,
            borderColor: 'rgba(99,110,114,1)',
            mainBoxFill: 'rgba(116,185,255,1)',
            mainLockBgColor: 'rgba(99,110,114,1)',
            mainShadowBgColor: 'rgba(104,165,227,1)',
            contentBoxFill: 'rgba(92,144,200,1)',
            topBoxFill: 'rgba(107,171,237,1)',
            ease: 'back.inOut(2)'
        })
    }

    out() {
        gsap.to(this.drawStyle.colorObj, {
            duration: this.baseDuration,
            borderColor: 'rgba(99,110,114,0)',
            mainBoxFill: 'rgba(116,185,255,0)',
            mainLockBgColor: 'rgba(99,110,114,0)',
            mainShadowBgColor: 'rgba(104,165,227,0)',
            contentBoxFill: 'rgba(92,144,200,0)',
            topBoxFill: 'rgba(107,171,237,0)',
            ease: 'back.inOut(2)'
        })
    }

    closeBox() {
        gsap.to(this.drawStyle.contentBox.rect, {
            duration: this.baseDuration,
            height: 0,
            preset: 1,
            width: 0.8,
            x: 0.1,
            y: 0.6,
            ease: 'back.inOut(2)'
        })
        gsap.to(this.drawStyle.contentBox, {
            duration: this.baseDuration,
            lineWidth: 8,
            ease: 'back.inOut(2)'
        })
        gsap.to(this.drawStyle.topBox.rect, {
            duration: this.baseDuration,
            height: 0,
            width: 1,
            x: 0,
            y: 0.55,
            ease: 'back.inOut(2)'
        })
    }

    openBox() {
        gsap.to(this.drawStyle.contentBox.rect, {
            duration: this.baseDuration,
            x: 0.11,
            y: 0.4,
            width: 0.78,
            height: 0.15,
            preset: 0.9,
            ease: 'back.inOut(2)'
        })
        gsap.to(this.drawStyle.contentBox, {
            duration: this.baseDuration,
            lineWidth: 10,
            ease: 'back.inOut(2)'
        })
        gsap.to(this.drawStyle.topBox.rect, {
            duration: this.baseDuration,
            x: 0.15,
            y: 0,
            width: 0.7,
            height: 0.4,
            ease: 'back.inOut(2)'
        })
    }

    private drawMainBox() {
        const rect = this.drawStyle.mainBox.rect
        const baseRect = new Rect(
            this.ctx,
            rect.x * this.drawStyle.size.width + this.drawStyle.position.x,
            rect.y * this.drawStyle.size.height + this.drawStyle.position.y,
            rect.width * this.drawStyle.size.width,
            rect.height * this.drawStyle.size.height,
            rect.radius
        )

        // 绘制主体
        this.ctx.fillStyle = this.drawStyle.colorObj.mainBoxFill
        this.ctx.lineWidth = this.drawStyle.base.lineWidth
        this.ctx.strokeStyle = this.drawStyle.colorObj.borderColor
        baseRect.drawRect()
        // 绘制箱子阴影
        this.ctx.fillStyle = this.drawStyle.colorObj.mainShadowBgColor
        const shadow = this.drawStyle.mainBox.shadow
        this.ctx.strokeStyle = 'transparent'
        new Rect(
            this.ctx,
            baseRect.x + baseRect.width * shadow.x,
            baseRect.y + baseRect.height * shadow.y,
            baseRect.width * shadow.width,
            baseRect.height * shadow.height,
            shadow.radius
        ).drawRect()
        // 绘制盒子锁
        this.ctx.fillStyle = this.drawStyle.colorObj.mainLockBgColor
        const lock = this.drawStyle.mainBox.lock
        this.ctx.strokeStyle = 'transparent'
        lock.data.forEach(item => {
            new Rect(
                this.ctx,
                baseRect.x + baseRect.width * item.x,
                baseRect.y + baseRect.height * item.y,
                baseRect.width * lock.width,
                baseRect.height * lock.height,
                lock.radius
            ).drawRect()
        })
    }

    private drawContentBox() {
        const rect = this.drawStyle.contentBox.rect
        this.ctx.fillStyle = this.drawStyle.colorObj.contentBoxFill
        this.ctx.lineWidth = this.drawStyle.contentBox.lineWidth
        this.ctx.strokeStyle = this.drawStyle.colorObj.borderColor
        new Rect(
            this.ctx,
            rect.x * this.drawStyle.size.width + this.drawStyle.position.x,
            rect.y * this.drawStyle.size.height + this.drawStyle.position.y,
            rect.width * this.drawStyle.size.width,
            rect.height * this.drawStyle.size.height,
            rect.radius,
            rect.preset,
            rect.type as 'top'
        ).drawRect();
    }

    private drawTopBox() {
        const rect = this.drawStyle.topBox.rect
        this.ctx.fillStyle = this.drawStyle.colorObj.topBoxFill
        this.ctx.lineWidth = this.drawStyle.topBox.lineWidth
        this.ctx.strokeStyle = this.drawStyle.colorObj.borderColor
        const baseRect = new Rect(
            this.ctx,
            rect.x * this.drawStyle.size.width + this.drawStyle.position.x,
            rect.y * this.drawStyle.size.height + this.drawStyle.position.y,
            rect.width * this.drawStyle.size.width,
            rect.height * this.drawStyle.size.height
        );
        baseRect.drawRect();

        // 绘制盒子锁
        this.ctx.fillStyle = this.drawStyle.colorObj.borderColor
        const lock = this.drawStyle.topBox.lock
        this.ctx.strokeStyle = 'transparent'
        lock.data.forEach(item => {
            new Rect(
                this.ctx,
                baseRect.x + baseRect.width * item.x,
                baseRect.y + baseRect.height * item.y,
                baseRect.width * lock.width,
                baseRect.height * lock.height,
                lock.radius
            ).drawRect()
        })
    }
}
